package com.laicunba.service.security.impl;

import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.SignatureException;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;

import org.apache.commons.codec.binary.Base64;
import org.springframework.stereotype.Service;

import com.laicunba.constant.GloabConstant;
import com.laicunba.service.security.SecurityService;

@Service
public class SecurityServiceImpl implements SecurityService {

	/**
	 * 公钥验证
	 * 
	 * @throws NoSuchAlgorithmException
	 * @throws InvalidKeySpecException
	 * @throws SignatureException
	 * @throws InvalidKeyException
	 */
	@Override
	public boolean verify(String src, String signStr) throws NoSuchAlgorithmException, InvalidKeySpecException, SignatureException, InvalidKeyException {
		KeyFactory keyFactory = KeyFactory.getInstance("RSA");

		X509EncodedKeySpec ps = new X509EncodedKeySpec(Base64.decodeBase64(GloabConstant.RSA_PUBLIC_KEY));
		PublicKey pkey = keyFactory.generatePublic(ps);

		Signature sign = Signature.getInstance("SHA1withRSA");
		sign.initVerify(pkey);
		sign.update(src.getBytes());
		return sign.verify(Base64.decodeBase64(signStr));
	}

	/**
	 * 私钥签名
	 * 
	 * @throws NoSuchAlgorithmException
	 * @throws InvalidKeySpecException
	 * @throws SignatureException
	 * @throws InvalidKeyException
	 */
	@Override
	public String sign(String srcString) throws NoSuchAlgorithmException, InvalidKeySpecException, InvalidKeyException, SignatureException {
		KeyFactory keyFactory = KeyFactory.getInstance("RSA");
		PKCS8EncodedKeySpec pkcs8 = new PKCS8EncodedKeySpec(Base64.decodeBase64(GloabConstant.RSA_PRIVATE_PKCS8_KEY));
		PrivateKey privateKey = keyFactory.generatePrivate(pkcs8);
		Signature sign = Signature.getInstance("SHA1withRSA");
		sign.initSign(privateKey);
		sign.update(srcString.getBytes());
		return Base64.encodeBase64String(sign.sign());
	}

	@Override
	public String encryptWithPrivate(String src) throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
		KeyFactory keyFactory = KeyFactory.getInstance("RSA");
		PKCS8EncodedKeySpec pkcs8 = new PKCS8EncodedKeySpec(Base64.decodeBase64(GloabConstant.RSA_PRIVATE_PKCS8_KEY));
		PrivateKey privateKey = keyFactory.generatePrivate(pkcs8);
		Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
		cipher.init(Cipher.ENCRYPT_MODE, privateKey);
		byte[] encryptData = cipher.doFinal(src.getBytes());
		return Base64.encodeBase64String(encryptData);
	}

	@Override
	public String decryptWithPublic(String encryptStr) throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException, InvalidKeyException, UnsupportedEncodingException {
		KeyFactory keyFactory = KeyFactory.getInstance("RSA");
		X509EncodedKeySpec x509 = new X509EncodedKeySpec(Base64.decodeBase64(GloabConstant.RSA_PUBLIC_KEY));
		PublicKey pubKey = keyFactory.generatePublic(x509);

		Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
		cipher.init(Cipher.DECRYPT_MODE, pubKey);
		byte[] decryptData = cipher.doFinal(Base64.decodeBase64(encryptStr));
		return new String(decryptData, "utf-8");
	}

	@Override
	public String encryptWithPublic(String src) throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
		KeyFactory keyFactory = KeyFactory.getInstance("RSA");
		X509EncodedKeySpec x509 = new X509EncodedKeySpec(Base64.decodeBase64(GloabConstant.RSA_PUBLIC_KEY));
		PublicKey pubKey = keyFactory.generatePublic(x509);
		Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
		cipher.init(Cipher.ENCRYPT_MODE, pubKey);
		byte[] encryptData = cipher.doFinal(src.getBytes());
		return Base64.encodeBase64String(encryptData);
	}

	@Override
	public String decryptWithPrivate(String encryptStr) throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException, InvalidKeyException, UnsupportedEncodingException {
		KeyFactory keyFactory = KeyFactory.getInstance("RSA");
		PKCS8EncodedKeySpec pkcs8 = new PKCS8EncodedKeySpec(Base64.decodeBase64(GloabConstant.RSA_PRIVATE_PKCS8_KEY));
		PrivateKey privateKey = keyFactory.generatePrivate(pkcs8);

		Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
		cipher.init(Cipher.DECRYPT_MODE, privateKey);
		byte[] decryptData = cipher.doFinal(Base64.decodeBase64(encryptStr));
		return new String(decryptData, "utf-8");
	}

}
